﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace game
{
    public class Radar
    {
        private Ship playerShip;
        private Scene scene;

        private Matrix cameraMatrix;
        private Matrix proj;

        private BasicPrimitives primitives;

        private float left;
        private float top;
        private float width;
        private float height;

        private const float gridLineOffset = 80000.0f;
        private const float gridRange = 700000.0f;
        private const float gridLineHalfLen = 700000.0f;

        public Radar(Scene scene, Ship ship)
        {
            this.scene = scene;
            this.playerShip = ship;
            primitives = ShooterGame.Instance.Primitives;
            primitives.Thickness = 2.0f;
            proj = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(25.0f), 1.0f, 1.0f, 100000.0f);

            float scrW = ShooterGame.Instance.GraphicsDevice.PresentationParameters.BackBufferWidth;
            float scrH = ShooterGame.Instance.GraphicsDevice.PresentationParameters.BackBufferHeight;

            left = scrW * 0.12f;
            top = scrH * 0.85f;
            width = scrW * 0.2f;
            height = scrH * 0.25f;
        }

        public void Update(GameTime gameTime)
        {
            Vector3 cameraPosition = new Vector3(0, 270000.0f, 0) + playerShip.Position
                + 600000.0f * Vector3.Transform(Vector3.Backward, Matrix.CreateRotationY(playerShip.Rotation.Y));
            Matrix view = Matrix.CreateLookAt(cameraPosition, playerShip.Position, Vector3.Up);

            cameraMatrix = view * proj;

        }

        public void DrawGrid()
        {
            Vector3 playerPos = playerShip.Position;
            Vector3 lineEnd1, lineEnd2, lineEndTrans1, lineEndTrans2;
            float x1, y1, x2, y2;

            lineEnd1.Y = lineEnd2.Y = playerPos.Y;
            float lineX = playerPos.X - gridRange;
            lineX = lineX - lineX % gridLineOffset;
            lineEnd1.Z = playerPos.Z + gridLineHalfLen;
            lineEnd2.Z = playerPos.Z - gridLineHalfLen;

            float end = playerPos.X + gridRange;
            for (; lineX <= end; lineX += gridLineOffset)
            {

                lineEnd1.X = lineEnd2.X = lineX;

                Vector3.Transform(ref lineEnd1, ref cameraMatrix, out lineEndTrans1);
                Vector3.Transform(ref lineEnd2, ref cameraMatrix, out lineEndTrans2);

                x1 = lineEndTrans1.X / lineEndTrans1.Z;
                y1 = -lineEndTrans1.Y / lineEndTrans1.Z;

                x2 = lineEndTrans2.X / lineEndTrans2.Z;
                y2 = -lineEndTrans2.Y / lineEndTrans2.Z;

                if (Line.Clip(ref x1, ref y1, ref x2, ref y2))
                    continue;

                x1 = x1 * width * 0.5f + left;
                y1 = y1 * height * 0.5f + top;

                x2 = x2 * width * 0.5f + left;
                y2 = y2 * height * 0.5f + top;

                primitives.Position = new Vector2(0, 0);

                primitives.CreateLine(new Vector2(x1, y1),
                    new Vector2(x2, y2));

                primitives.RenderLinePrimitive(ShooterGame.Instance.SpriteBatch);
            }

            float lineZ = playerPos.Z - gridRange;
            lineZ = lineZ - lineZ % gridLineOffset;
            lineEnd1.X = playerPos.X + gridLineHalfLen;
            lineEnd2.X = playerPos.X - gridLineHalfLen;

            end = playerPos.Z + gridRange;
            for (; lineZ < end; lineZ += gridLineOffset)
            {
                lineEnd1.Z = lineEnd2.Z = lineZ;

                Vector3.Transform(ref lineEnd1, ref cameraMatrix, out lineEndTrans1);
                Vector3.Transform(ref lineEnd2, ref cameraMatrix, out lineEndTrans2);

                x1 = lineEndTrans1.X / lineEndTrans1.Z;
                y1 = -lineEndTrans1.Y / lineEndTrans1.Z;

                x2 = lineEndTrans2.X / lineEndTrans2.Z;
                y2 = -lineEndTrans2.Y / lineEndTrans2.Z;

                if (Line.Clip(ref x1, ref y1, ref x2, ref y2))
                    continue;

                x1 = x1 * width * 0.5f + left;
                y1 = y1 * height * 0.5f + top;

                x2 = x2 * width * 0.5f + left;
                y2 = y2 * height * 0.5f + top;

                primitives.Position = new Vector2(0, 0);

                primitives.CreateLine(new Vector2(x1, y1),
                    new Vector2(x2, y2));

                primitives.RenderLinePrimitive(ShooterGame.Instance.SpriteBatch);
            }
        }

        public void Draw(GameTime gameTime)
        {
            ShooterGame.Instance.SpriteBatch.Begin();

            primitives.Colour = Color.CornflowerBlue;
            primitives.Position = new Vector2(0, 0);
            primitives.CreateSquare(new Vector2(left - width * 0.5f, top - height * 0.5f), new Vector2(left + width * 0.5f, top + height * 0.5f));
            primitives.RenderPolygonPrimitive(ShooterGame.Instance.SpriteBatch);


            DrawGrid();


           foreach(GameObject obj in scene)
           {
                if (obj is Ship)
                {
                    Vector3 objPos = obj.Position;
                    Vector3 pos = Vector3.Transform(objPos, cameraMatrix);
                    float x = pos.X / pos.Z;
                    float y = -pos.Y / pos.Z;


                    float scrX, scrY;

                    scrX = x * width * 0.5f + left;
                    scrY = y * height * 0.5f + top;

                    if (x <= 1.0f && x >= -1.0f && y <= 1.0f && y >= -1.0f)
                    {

                        primitives.Position = new Vector2(scrX, scrY);

                        if (obj == playerShip)
                        {
                            primitives.Colour = Color.White;
                            primitives.CreateTriangle(new Vector2(-3.0f, 3.0f), new Vector2(3.0f, 3.0f), new Vector2(0.0f, -3.0f));
                        }
                        else
                        {
                            primitives.Colour = ((Ship)obj).Squadron.Army.Color;
                            primitives.CreateCircle(2, 32);
                        }

                        primitives.RenderPolygonPrimitive(ShooterGame.Instance.SpriteBatch);


                    }

                    if (obj.LayerIndex != playerShip.LayerIndex)
                    {
                        Vector3 posProjected = obj.Position;
                        posProjected.Y = playerShip.Position.Y;

                        Vector3 posPTransformed = Vector3.Transform(posProjected, cameraMatrix);

                        float xP = posPTransformed.X / posPTransformed.Z;
                        float yP = -posPTransformed.Y / posPTransformed.Z;

                        if (Line.Clip(ref x, ref y, ref xP, ref yP))
                            continue;

                        xP = xP * width * 0.5f + left;
                        yP = yP * height * 0.5f + top;

                        scrX = x * width * 0.5f + left;
                        scrY = y * height * 0.5f + top;

                        primitives.Position = new Vector2(0, 0);

                        primitives.Colour = ((Ship)obj).Squadron.Army.Color;
                        primitives.CreateLine(new Vector2(xP, yP),
                            new Vector2(scrX, scrY));

                        primitives.RenderLinePrimitive(ShooterGame.Instance.SpriteBatch);

                    }
                }


            }

            ShooterGame.Instance.SpriteBatch.End();
        }
    }
}
